package com.wstuo.common.security.service;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.file.csv.CSVReader;
import com.wstuo.common.file.csv.CSVWriter;
import com.wstuo.common.security.dao.IFunctionDAO;
import com.wstuo.common.security.dao.IOperationDAO;
import com.wstuo.common.security.dao.IResourceDAO;
import com.wstuo.common.security.dao.IUserDAO;
import com.wstuo.common.security.dto.OperationDTO;
import com.wstuo.common.security.dto.OperationQueryDTO;
import com.wstuo.common.security.entity.Function;
import com.wstuo.common.security.entity.Operation;
import com.wstuo.common.security.utils.AppContext;
import com.wstuo.common.security.utils.FileEncodeUtils;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.StringUtils;

/**
 * 操作业务类
 */
@SuppressWarnings("unchecked")
public class OperationService implements IOperationService {

	private static final Logger LOGGER = Logger.getLogger(OperationService.class);

	@Autowired
	private IOperationDAO operationDAO;
	@Autowired
	private IFunctionDAO functionDAO;
	@Autowired
	private IResourceDAO resourceDAO;
	@Autowired
	private IFunctionService functionService;
	@Autowired
	private IUserDAO userDAO;
	@Autowired
	private AppContext appctx;

	/**
	 * 分页查找操作.
	 * 
	 * @param operationQueryDTO
	 *            分页查询DTO：OperationQueryDTO
	 * @return 分页数据：PageDTO
	 */
	public PageDTO findPagerOperation(OperationQueryDTO operationQueryDTO) {
		PageDTO p = operationDAO.findPager(operationQueryDTO);
		List<Operation> entities = (List<Operation>) p.getData();
		List<OperationDTO> dtos = new ArrayList<OperationDTO>(entities.size());

		for (Operation entity : entities) {
			OperationDTO dto = new OperationDTO();
			OperationDTO.entity2dto(entity, dto);
			if((!"/pages/role!setResourceByRoleIds.action".equals(entity.getResUrl())
					&& !"/pages/user!updateRoleByUserId.action".equals(entity.getResUrl()))
					|| userDAO.isExistRoleByUserLoginName(appctx.getCurrentLoginName(), IRoleService.ROLE_SYSADMIN)){
				dtos.add(dto);
			}
		}

		p.setData(dtos);

		return p;
	}

	/**
	 * 新增操作.
	 * 
	 * @param operationDTO
	 *            操作DTO:OperationDTO
	 */
	@Transactional()
	public void addOperation(OperationDTO operationDTO) {
		Operation entity = new Operation();

		OperationDTO.dto2entity(operationDTO, entity);

		if (operationDTO.getFunctionNo() != null) {
			Function function = functionDAO.findById(operationDTO.getFunctionNo());
			entity.setFunction(function);
		} else {// tan add 20110721
			if (operationDTO.getFunctionResCode() != null) {
				Function function = functionDAO.findUniqueBy("resCode", operationDTO.getFunctionResCode());
				entity.setFunction(function);
			}
		}

		operationDAO.save(entity);
		operationDTO.setResNo(entity.getResNo());
	}

	/**
	 * 编辑操作.
	 * 
	 * @param operationDto
	 *            操作DTO：OperationDTO
	 */
	@Transactional()
	public void upadteOperation(OperationDTO operationDto) {

		// 验证数据
		resourceDAO.findExists2(operationDto.getResName(), operationDto.getResCode(), operationDto.getResUrl(), operationDto.getResNo());

		Operation entity = operationDAO.findById(operationDto.getResNo());

		if (operationDto.getResName() != null) {
			entity.setResName(operationDto.getResName());
		}

		if (operationDto.getResCode() != null) {
			entity.setResCode(operationDto.getResCode());
		}

		if (operationDto.getResIcon() != null) {
			entity.setResIcon(operationDto.getResIcon());
		}

		if (operationDto.getResUrl() != null) {
			entity.setResUrl(operationDto.getResUrl());
		}

		operationDAO.merge(entity);
	}

	/**
	 * 根据编号删除操作.
	 * 
	 * @param resNo
	 *            操作编号：Long resNo
	 * @return boolean true为删除成功，反之失败
	 */
	@Transactional()
	public Boolean deleteOperation(Long resNo) {
		Boolean result = true;
		Byte delete = 1;
		Operation entity = operationDAO.findById(resNo);

		if (entity.getDataFlag().toString().equals(delete.toString())) {
			result = false;
		}
		if (result) {
			operationDAO.delete(entity);
		}

		return result;
	}

	/**
	 * 批量删除操作.
	 * 
	 * @param resNos
	 *            操作编号数组：Long[] resNos
	 * @return boolean true为删除成功，反之失败
	 */
	@Transactional()
	public Boolean deleteOperations(Long[] resNos) {
		Boolean result = true;
		Byte delete = 1;

		for (Long id : resNos) {
			Operation opt = operationDAO.findById(id);
			if (opt.getDataFlag().toString().equals(delete.toString())) {
				result = false;
			}
		}

		if (result) {
			operationDAO.deleteByIds(resNos);
		}

		return result;
	}

	/**
	 * 查询操作是否存在.
	 * 
	 * @param qdto
	 *            操作DTO：OperationQueryDTO
	 */
	public Boolean findOperationExist(OperationQueryDTO qdto) {
		return operationDAO.findExist(qdto);
	}

	/**
	 * 根据ID获取OperationDTO
	 * 
	 * @param resNo
	 *            Long resNo return OperationDTO
	 */
	@Transactional
	public OperationDTO findById(Long resNo) {
		OperationDTO dto = new OperationDTO();
		Operation entity = operationDAO.findById(resNo);
		if (entity != null) {
			OperationDTO.entity2dto(entity, dto);
		}

		return dto;

	}

	/**
	 * 导出资源（操作）.
	 * 
	 * @param qdto
	 * @return InputStream
	 */
	@Transactional
	public InputStream exportOperation(OperationQueryDTO qdto) {
		LanguageContent lc = LanguageContent.getInstance();
		List<String[]> data = new ArrayList<String[]>();
		data.add(new String[] { lc.getContent("label.sla.operation") + "ID", lc.getContent("label.role.roleName"), lc.getContent("label.resource.operationCode"), lc.getContent("label.resource.functionUrl"), lc.getContent("label.resource.functionIcon"), lc.getContent("title.resource.parentFunction") });// 加入表头

		// 升序排列
		qdto.setSord("asc");
		qdto.setSidx("resNo");
		qdto.setLimit(1000000);// 无限大

		PageDTO p = operationDAO.findPager(qdto);
		List<Operation> entities = (List<Operation>) p.getData();

		String function = "";

		for (Operation op : entities) {

			if (op.getFunction() != null) {
				function = op.getFunction().getResName();
			}
			data.add(new String[] { op.getResNo() + "", op.getResName(), op.getResCode() + "", op.getResUrl(), op.getResIcon(), function });
			function = "";
		}

		StringWriter sw = new StringWriter();
		CSVWriter csvw = new CSVWriter(sw);
		csvw.writeAll(data);
		
		byte[] bs = null;
		try {
			bs = sw.getBuffer().toString().getBytes("GBK");
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		ByteArrayInputStream stream = null;
		if(bs!=null){
			stream = new ByteArrayInputStream(bs);
		}

		try {
			if (csvw != null) {
				csvw.flush();
				csvw.close();
			}
			if (sw != null) {
				sw.flush();
				sw.close();
			}
		} catch (IOException e) {
			LOGGER.error(e);
		}
		return stream;
	}

	/**
	 * 导入资源（操作）.
	 * 
	 * @param filePath
	 *            导入文件路径
	 * @return import result
	 */
	@Transactional
	public String importOperation(String filePath) {
		String result = "";
		try {
			String fileEncode = FileEncodeUtils.getFileEncode(new File(filePath));
			Reader rd = new InputStreamReader(new FileInputStream(filePath), fileEncode);// 以字节流方式读取数据
			CSVReader reader = new CSVReader(rd);
			String[] line = null;

			while ((line = reader.readNext()) != null) {

				Operation op = new Operation();
				op.setResNo(Long.parseLong(line[0].toString()));
				op.setResName(line[1].toString());
				op.setResCode(line[2].toString());
				op.setResUrl(line[3].toString());
				op.setResIcon(line[4].toString());

				if (StringUtils.hasText(line[5].toString())) {// 关联父功能
					op.setFunction(functionService.getFunctionByFunctionNoStr(line[5].toString()));
				}
				if (StringUtils.hasText(line[6]))
					op.setDataFlag((byte) Integer.parseInt(line[6]));

				operationDAO.save(op);
			}
			result = "success";

		} catch (Exception ex) {
			LOGGER.error(ex);
			result = "failure";
		}
		return result;

	}

}
